﻿using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Collections.Generic;
using Microsoft.WindowsAzure.ServiceRuntime;


namespace McHotspoot
{
    public class _RandBar : McHotspotI
    {
        public string execute(string key, double n, double index, string codein, out string message)
        {
            string filename = "process"; double myN = 1;
            string filesRoot = RoleEnvironment.GetLocalResource("McCloudStorage").RootPath;
            string matlab1 = Path.Combine(filesRoot, filename + ".exe");
            string output1 = "P_" + key + index + ".csv";

            exec(matlab1, new string[] {myN.ToString(), index.ToString(), codein, output1}, out message);
            FileStream fileStream = new FileStream(output1, FileMode.Open);
            StreamReader reader = new StreamReader(fileStream);
            string r = reader.ReadToEnd();
            fileStream.Close();
            return r;
            
        }

        public string finish(string key, double n, string r, string codein, string codeout, 
            out string message)
        {
            string filename = "merge"; double myN = ((Math.Log(n, Math.E) / Math.Log(4, Math.E))-3);
            string filesRoot = RoleEnvironment.GetLocalResource("McCloudStorage").RootPath;
            string matlab2 = Path.Combine(filesRoot, filename + ".exe");
            string output1 = r;            
            string output2 = "M_" + key + ".csv";
            exec(matlab2, new string[] { myN.ToString(), output1, output2 }, out message);
            string m = "";
            FileStream fileStream2 = new FileStream(output2, FileMode.OpenOrCreate);
            StreamReader reader = new StreamReader(fileStream2);
            m = reader.ReadToEnd();
            fileStream2.Close();
            return m;            
        }

        public void optimization(double n, string codein, string codeout, double npt, 
            out double ninstancesadded, out double ntasks, out int timeoutInSeconds)
        {   
            double nTasks = n / 256;
            ntasks = Decimal.ToInt32(Decimal.Truncate((decimal)(nTasks)));
            ninstancesadded = 0;
            timeoutInSeconds = 2 * 60 * 60; // Máximo 2 horas
        }

        public string test(string key, double n, string codein, string codeout, double npt)
        {
            if (codein != "1" && codein != "0" && codein != "2" && codein != "3") return "Error: Incorrect Imput";            
            return "";
        }
        
        private void exec(string file, string[] arguments, out string message)
        {
            if (!System.IO.File.Exists(file))
            {
                message = "Executável inexistente: " + file;
                return;
            }
            System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo();
            psi.FileName = file;
            psi.Arguments = "";
            for (int i = 0; i < arguments.Length; i++)
            {
                psi.Arguments += " \"" + arguments[i] + "\"";
            }
            psi.Arguments = string.Format(psi.Arguments);
            psi.CreateNoWindow = true;
            psi.ErrorDialog = false;
            psi.UseShellExecute = false;
            psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            psi.RedirectStandardOutput = true;
            psi.RedirectStandardInput = false;
            psi.RedirectStandardError = true;
                        
            System.Diagnostics.Process exeProcess = System.Diagnostics.Process.Start(psi);
            exeProcess.PriorityClass = System.Diagnostics.ProcessPriorityClass.High;
            exeProcess.OutputDataReceived += 
                new System.Diagnostics.DataReceivedEventHandler(processOutputHandler);
            exeProcess.BeginOutputReadLine();
            string errString = exeProcess.StandardError.ReadToEnd();
            exeProcess.WaitForExit();
            exeProcess.Close();
            message = "Exec: " + psi.FileName + " " + psi.Arguments + "\r\n";
            if (errString != "") message += "Exec Erro: " + errString;
            if (_output != "") message += "Exec Saída: " + _output;
        }

        private string _output = "";
        private void processOutputHandler(object sendingProcess, 
            System.Diagnostics.DataReceivedEventArgs outLine)
        {
            if (!String.IsNullOrEmpty(outLine.Data)) _output += outLine.Data+"\r\n";
        }
    }
}